/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */

/* 
 * Hum -- The Low Calorie Music Manager
 * 
 * Copyright (C) 2007 by Brian Davis <brian.william.davis@gmail.com>
 *
 * This file is modifiable/redistributable under the terms of the GNU
 * General Public License.
 *
 * You should have recieved a copy of the GNU General Public License along
 * with this program; see the file COPYING. If not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
 */

#include "hum_ui.h"
#include "hum_player.h"

// FIXME: Hook up keyboard shortcuts and menu items. 
void
hum_init_ui ()
{
	hum_debug (__func__, "Initializing the UI...\n");
	hum_app.xml = glade_xml_new (HUM_GLADE_FILE, NULL, NULL);
	
	hum_app.window = GTK_WINDOW (glade_xml_get_widget (hum_app.xml, "main_window"));
	hum_app.statusbar = GTK_STATUSBAR (glade_xml_get_widget (hum_app.xml, "statusbar"));
	hum_app.prev_button = GTK_TOOL_BUTTON (glade_xml_get_widget (hum_app.xml, "prev_button"));
	hum_app.play_button = GTK_TOGGLE_TOOL_BUTTON (glade_xml_get_widget (hum_app.xml, "play_button"));
	hum_app.stop_button = GTK_TOOL_BUTTON (glade_xml_get_widget (hum_app.xml, "stop_button"));
	hum_app.next_button = GTK_TOOL_BUTTON (glade_xml_get_widget (hum_app.xml, "next_button"));
	hum_app.track_label = GTK_LABEL (glade_xml_get_widget (hum_app.xml, "track_label"));
	hum_app.duration_label = GTK_LABEL (glade_xml_get_widget (hum_app.xml, "duration_label"));
	hum_app.search_entry = GTK_ENTRY (glade_xml_get_widget (hum_app.xml, "search_entry"));
	hum_app.search_button = GTK_BUTTON (glade_xml_get_widget (hum_app.xml, "search_button"));
	hum_app.slider = GTK_HSCALE (glade_xml_get_widget (hum_app.xml, "slider"));
	hum_app.track_list = GTK_TREE_VIEW (glade_xml_get_widget (hum_app.xml, "track_list"));
	
	hum_app.tag_dialog = GTK_DIALOG (glade_xml_get_widget (hum_app.xml, "tag_dialog"));
	hum_app.tag_entry = GTK_ENTRY (glade_xml_get_widget (hum_app.xml, "tag_entry"));
	hum_app.tag_cancel = GTK_BUTTON (glade_xml_get_widget (hum_app.xml, "tag_cancel"));
	hum_app.tag_apply = GTK_BUTTON (glade_xml_get_widget (hum_app.xml, "tag_apply"));
	
	/* Set the window icon. */
	gtk_window_set_icon_from_file (hum_app.window, "hum.png", NULL);
	
	/* Initialize the store and view. */
	hum_init_view ();
	
	/* Hook up UI signals to the appropriate callbacks. */
	g_signal_connect (G_OBJECT (hum_app.prev_button), "clicked", G_CALLBACK (hum_prev_button_clicked), NULL);
	g_signal_connect (G_OBJECT (hum_app.play_button), "toggled", G_CALLBACK (hum_play_button_toggled), NULL);
	g_signal_connect (G_OBJECT (hum_app.stop_button), "clicked", G_CALLBACK (hum_stop_button_clicked), NULL);
	g_signal_connect (G_OBJECT (hum_app.next_button), "clicked", G_CALLBACK (hum_next_button_clicked), NULL);
	g_signal_connect (G_OBJECT (hum_app.search_entry), "activate", G_CALLBACK (hum_search_activated), NULL);
	g_signal_connect (G_OBJECT (hum_app.search_button), "clicked", G_CALLBACK (hum_search_activated), NULL);
	g_signal_connect (G_OBJECT (hum_app.slider), "change-value", G_CALLBACK (hum_slider_moved), NULL);
	g_signal_connect (G_OBJECT (hum_app.window), "destroy", G_CALLBACK(hum_quit), NULL);
	
	// FIXME: Hook up menu signals.
	g_signal_connect (G_OBJECT (glade_xml_get_widget (hum_app.xml, "about_menu_item")), "activate", G_CALLBACK (hum_show_about_dialog), NULL);
	
	gtk_widget_show (GTK_WIDGET (hum_app.track_list));
	
	hum_debug (__func__, "Finished initializing the UI.\n");
}

void
hum_init_view ()
{
	GtkTreeViewColumn *uri, *status, *track, *title, *genre, *artist, *album, *length;
	GtkWidget *status_header;
	
	hum_debug (__func__, "Creating the view...\n");
	
	hum_init_store ();	
	gtk_tree_view_set_model (hum_app.track_list, GTK_TREE_MODEL (hum_app.store));
	
	status = gtk_tree_view_column_new_with_attributes ("", gtk_cell_renderer_pixbuf_new (), "stock-id", HUM_COL_STATUS, NULL);	
	uri = gtk_tree_view_column_new_with_attributes ("URI", gtk_cell_renderer_text_new (), "text", HUM_COL_URI, NULL);
	title = gtk_tree_view_column_new_with_attributes ("Title", gtk_cell_renderer_text_new (), "text", HUM_COL_TITLE, NULL);
	artist = gtk_tree_view_column_new_with_attributes ("Artist", gtk_cell_renderer_text_new (), "text", HUM_COL_ARTIST, NULL);
	album = gtk_tree_view_column_new_with_attributes ("Album", gtk_cell_renderer_text_new (), "text", HUM_COL_ALBUM, NULL);
	track = gtk_tree_view_column_new_with_attributes ("#", gtk_cell_renderer_text_new (), "text", HUM_COL_TRACK_NO, NULL);
	genre = gtk_tree_view_column_new_with_attributes ("Genre", gtk_cell_renderer_text_new (), "text", HUM_COL_GENRE, NULL);
	length = gtk_tree_view_column_new_with_attributes ("Length", gtk_cell_renderer_text_new (), "text", HUM_COL_DURATION, NULL);
	
	gtk_tree_view_column_set_visible (uri, FALSE);
	gtk_tree_view_column_set_sizing (status, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (title, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (artist, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (album, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (track, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (genre, GTK_TREE_VIEW_COLUMN_FIXED);
	gtk_tree_view_column_set_sizing (length, GTK_TREE_VIEW_COLUMN_FIXED);
	
	gtk_tree_view_column_set_fixed_width (status, 22);
	status_header = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU);
	gtk_tree_view_column_set_widget (status, status_header);
	gtk_widget_show (status_header);
	
	gtk_tree_view_column_set_expand (title, TRUE);
	gtk_tree_view_column_set_expand (artist, TRUE);
	gtk_tree_view_column_set_expand (album, TRUE);
	gtk_tree_view_column_set_fixed_width (track, 48);
	gtk_tree_view_column_set_expand (genre, TRUE);
	gtk_tree_view_column_set_fixed_width (length, 72);
	
	gtk_tree_view_column_set_resizable (title, TRUE);
	gtk_tree_view_column_set_resizable (artist, TRUE);
	gtk_tree_view_column_set_resizable (album, TRUE);
	gtk_tree_view_column_set_resizable (track, FALSE);
	gtk_tree_view_column_set_resizable (genre, TRUE);
	gtk_tree_view_column_set_resizable (length, FALSE);
	
	//gtk_tree_view_column_set_sort_column_id (status, HUM_COL_STATUS);
	gtk_tree_view_column_set_sort_column_id (title, HUM_COL_TITLE);
	gtk_tree_view_column_set_sort_column_id (artist, HUM_COL_ARTIST);
	gtk_tree_view_column_set_sort_column_id (album, HUM_COL_ALBUM);
	gtk_tree_view_column_set_sort_column_id (genre, HUM_COL_GENRE);
	gtk_tree_view_column_set_sort_column_id (track, HUM_COL_TRACK_NO);
	gtk_tree_view_column_set_sort_column_id (length, HUM_COL_DURATION);
	
	gtk_tree_view_append_column (hum_app.track_list, uri);
	gtk_tree_view_append_column (hum_app.track_list, status);
	gtk_tree_view_append_column (hum_app.track_list, title);
	gtk_tree_view_append_column (hum_app.track_list, artist);
	gtk_tree_view_append_column (hum_app.track_list, album);
	gtk_tree_view_append_column (hum_app.track_list, track);
	gtk_tree_view_append_column (hum_app.track_list, genre);
	gtk_tree_view_append_column (hum_app.track_list, length);
	
	g_signal_connect (G_OBJECT (hum_app.track_list), "row-activated", G_CALLBACK (hum_song_selected), NULL);
	
	hum_app.browse_select = gtk_tree_view_get_selection (GTK_TREE_VIEW (hum_app.track_list));
	gtk_tree_selection_set_mode (hum_app.browse_select, GTK_SELECTION_SINGLE);
    
    hum_debug (__func__, "Finished creating the view.\n");
}

void
hum_init_store ()
{
	/* Create a store with columns for: uri, status, track number, title, genre, artist, album, length. */
	hum_debug (__func__, "Creating the store...\n");
	
	hum_app.store = gtk_list_store_new (HUM_COL_N_COLS, 
									   	G_TYPE_STRING, 	// URI
									   	G_TYPE_STRING,	// play/pause icon
									   	G_TYPE_STRING, 	// title
									   	G_TYPE_STRING, 	// artist
									   	G_TYPE_STRING, 	// album
									   	G_TYPE_STRING, 	// track number
									   	G_TYPE_STRING, 	// genre
									   	G_TYPE_STRING);	// length
	
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_TITLE, hum_title_sort, NULL, NULL);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_ARTIST, hum_artist_sort, NULL, NULL);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_ALBUM, hum_album_sort, NULL, NULL);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_GENRE, hum_genre_sort, NULL, NULL);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_TRACK_NO, hum_album_sort, NULL, NULL);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (hum_app.store), HUM_COL_DURATION, hum_duration_sort, NULL, NULL);
	
	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (hum_app.store), HUM_COL_ARTIST, GTK_SORT_ASCENDING);
    
    hum_debug (__func__, "Finished creating the store.\n");
}

void
hum_show_about_dialog ()
{
	hum_debug (__func__, "Triggered.\n");
	
	const gchar *authors[] = {"Brian Davis <brian.william.davis@gmail.com>", NULL};
	const gchar *comments = "The low calorie music player.";
	const gchar *copyright = "Copyright © 2007 Brian Davis";
	const gchar *license = "This program is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as\npublished by the Free Software Foundation; either version 2 of the\nLicense, or (at your option) any later version.\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.";
	GdkPixbuf *logo = gdk_pixbuf_new_from_file (HUM_LOGO_FILE, NULL);
	
	gtk_show_about_dialog (hum_app.window, 
		"authors", authors,
		"comments", comments,
		"copyright", copyright,
		"license", license,
		"logo", logo,
		"name", "Hum",
		"version", "0.1",
		"website", "http://code.google.com/p/hum-gtk",
		NULL);
}

void
hum_clear_track_list ()
{
	hum_debug (__func__, "Triggered.\n");
	
	GtkTreeIter iter, iter_next;
	
	if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (hum_app.store), &iter))
	{
		iter_next = iter;
		
		while (gtk_tree_model_iter_next (GTK_TREE_MODEL (hum_app.store), &iter_next))
		{
			gtk_tree_iter_free (&iter);
			iter = iter_next;
		}
		
		gtk_tree_iter_free (&iter_next);
	}
}

/*
 *
 * Sort by title. 
 *
 */
 
gint
hum_title_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *title_a, *title_b;
	guint sort;
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_TITLE, &title_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_TITLE, &title_b, -1);
	
	sort = hum_utf8_strcmp (title_a, title_b);
	
	g_free (title_a);
	g_free (title_b);
	
	return sort;
}

/*
 *
 * Sort by artist (actually sorts by artist->album->track). 
 *
 */
 
gint
hum_artist_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *artist_a, *artist_b;
	guint sort; 
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_ARTIST, &artist_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_ARTIST, &artist_b, -1);
	
	//hum_debug (__func__, "Comparing %s and %s\n", artist_a, artist_b);
	
	sort = hum_utf8_strcmp (artist_a, artist_b);
	
	/* Both tracks are by the same artist. */
	if (sort == 0)
	{
		sort = hum_album_sort (model, a, b, data);
	}
	
	g_free (artist_a);
	g_free (artist_b);
	
	return sort;
}

gint
hum_album_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *album_a, *album_b;
	guint sort; 
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_ALBUM, &album_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_ALBUM, &album_b, -1);
	
	sort = hum_utf8_strcmp (album_a, album_b);
	
	/* Both tracks are off of the same album. */
	if (sort == 0)
	{
		sort = hum_track_sort (model, a, b, data);
	}
	
	g_free (album_a);
	g_free (album_b);
	
	return sort;
}

gint
hum_track_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *track_a, *track_b;
	guint num_a, num_b, sort;
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_TRACK_NO, &track_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_TRACK_NO, &track_b, -1);
	
	num_a = atoi (track_a);
	num_b = atoi (track_b);
	
	if (num_a != num_b)
	{
		sort = (num_a > num_b) ? 1 : -1;
	}
	else
	{
		sort = 0;
	}

	g_free (track_a);
	g_free (track_b);
	
	return sort;
}

gint
hum_genre_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *genre_a, *genre_b;
	guint sort;
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_GENRE, &genre_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_GENRE, &genre_b, -1);
	
	sort = hum_utf8_strcmp (genre_a, genre_b);
	
	if (sort == 0)
	{
		sort = hum_album_sort (model, a, b, data);
	}
	
	g_free (genre_a);
	g_free (genre_b);
	
	return sort;
}

gint
hum_duration_sort (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
{
	gchar *duration_a, *duration_b;
	guint sort;
	
	//hum_debug (__func__, "Triggered.\n");
	
	gtk_tree_model_get (model, a, HUM_COL_DURATION, &duration_a, -1);
	gtk_tree_model_get (model, b, HUM_COL_DURATION, &duration_b, -1);
	
	sort = hum_utf8_strcmp (duration_a, duration_b);

	g_free (duration_a);
	g_free (duration_b);
	
	return sort;
}

void
hum_search_activated (GtkWidget *b, gpointer data)
{
	hum_debug (__func__, "Triggered.\n");
	
	const gchar *entry;
	
	entry = gtk_entry_get_text (hum_app.search_entry);
	
	if (strcmp (entry, "") != 0)
	{
		tracker_search_query_async (hum_app.client, -1, SERVICE_MUSIC, audio_keys, entry, "", "", 0, 512, TRUE, (TrackerGPtrArrayReply) hum_populate_store_async, NULL);
	}
}

void
hum_populate_store_async (GPtrArray *result, GError *error, gpointer data)
{
	gint i;
	
	if (!error && result != NULL) {
		hum_debug (__func__, "Got population request...\n");
		
		// FIXME: Break this out into a convenience function for use elsewhere.
		// It should probably be named something like 'hum_clear_track_list'.
		gtk_list_store_clear (hum_app.store);
		//hum_clear_track_list ();
		
		hum_app.total_duration = 0;
		hum_app.total_song_size = 0;
		hum_app.total_song_count = 0;
		
		// FIXME: Technically, we've already got all the information we need,
		// since our query asked for all the fields in 'audio_keys'. Thus, 
		// we're going through extra work when we make an additional request
		// for this same data in 'hum_populate_row'. 'hum_populate_row' 
		// should be more generic, accepting information and blindly
		// inserting it into the store. 
		for (i = 0; i < result->len; i++)
		{
			hum_populate_row (((gchar**) result->pdata[i])[0]);
		}
			
		hum_update_stats ();
			
		while (gtk_events_pending ())
		{
			gtk_main_iteration ();
		}
	}
	
	g_clear_error (&error);
	g_ptr_array_free (result, TRUE);
}

void
hum_populate_row (gchar *uri)
{
	gchar **meta;
	gchar *track, *title, *genre, *artist, *album, *duration;
	GError *error = NULL;
	GtkTreeIter iter;
	
	hum_debug (__func__, "Fetching metadata for %s\n", uri);	
	meta = tracker_metadata_get (hum_app.client, SERVICE_MUSIC, uri, audio_keys, &error);
	
	if (meta && !error)
	{
		if (!meta[AUDIO_TRACK_NO])
		{
			hum_debug (__func__, "Setting track to ''\n");
			track = g_strdup ("");
		}
		else
		{
			
			hum_debug (__func__, "Setting track to '%s'\n", meta[AUDIO_TRACK_NO]);
			if (atoi (meta[AUDIO_TRACK_NO]) > 0)
			{
				track = g_strdup_printf ("%u", atoi (meta[AUDIO_TRACK_NO]));
			}
			else
			{
				track = g_strdup ("");
			}
		}
		
		if (!meta[AUDIO_TITLE] || g_utf8_strlen (meta[AUDIO_TITLE], -1) < 1)
		{
			title = g_path_get_basename (uri);
			//title = hum_remove_escapes (title);
			//title = g_markup_escape_text (title, -1);
			//title = g_strcompress (title); // remove escape delimiters
			hum_debug (__func__, "Setting title to '%s'\n", title);
		}
		else
		{
			title = g_strdup (meta[AUDIO_TITLE]);
			//title = hum_remove_escapes (title);
			//title = g_strcompress (title); // remove escape delimiters
			//title = g_markup_escape_text (title, -1);
			hum_debug (__func__, "Setting title to '%s'\n", title);
		}
		
		if (!meta[AUDIO_GENRE] || g_utf8_strlen (meta[AUDIO_GENRE], -1) < 1)
		{
			hum_debug (__func__, "Setting genre to 'Unknown'\n");
			genre = g_strdup ("Unknown");
		}
		else
		{
			hum_debug (__func__, "Setting genre to '%s'\n", meta[AUDIO_GENRE]);
			genre = g_strdup (meta[AUDIO_GENRE]);
			//genre = hum_remove_escapes (genre);
		}
		
		if (!meta[AUDIO_ARTIST] || g_utf8_strlen (meta[AUDIO_ARTIST], -1) < 1)
		{
			hum_debug (__func__, "Setting artist to 'Unknown'\n");
			artist = g_strdup ("Unknown");
		}
		else
		{
			hum_debug (__func__, "Setting artist to '%s'\n", meta[AUDIO_ARTIST]);
			artist = g_strdup (meta[AUDIO_ARTIST]);
			//artist = hum_remove_escapes (artist);
		}
		
		if (!meta[AUDIO_ALBUM] || g_utf8_strlen (meta[AUDIO_ALBUM], -1) < 1)
		{
			hum_debug (__func__, "Setting album to 'Unknown'\n");
			album = g_strdup ("Unknown");
		}
		else
		{
			hum_debug (__func__, "Setting album to '%s'\n", meta[AUDIO_ALBUM]);
			album = g_strdup (meta[AUDIO_ALBUM]);
			//album = hum_remove_escapes (album);
		}
		
		if (!meta[AUDIO_DURATION] || g_utf8_strlen (meta[AUDIO_DURATION], -1) < 1)
		{
			hum_debug (__func__, "Setting duration to '0:00'\n");
			duration = g_strdup ("00:00");
			hum_app.total_duration += 0;
		}
		else
		{
			hum_debug (__func__, "Converting duration from %s\n", meta[AUDIO_DURATION]);			
			guint seconds;
			guint minutes;
			
			seconds = (guint) (g_ascii_strtod (meta[AUDIO_DURATION], NULL));
			minutes = (guint) (seconds / 60);
			seconds = (guint) (seconds % 60);
			
			duration = g_strdup_printf ("%02u:%02u", minutes, seconds);
			
			hum_app.total_duration += (guint) (g_ascii_strtod (meta[AUDIO_DURATION], NULL));
		}
		
		if (!meta[AUDIO_SIZE] || g_utf8_strlen (meta[AUDIO_SIZE], -1) < 1)
		{
			hum_debug (__func__, "Setting size to '0'\n");
			hum_app.total_song_size += 0;
		}
		else
		{
			hum_debug (__func__, "Converting size from %s\n", meta[AUDIO_SIZE]);
			hum_app.total_song_size += (guint) (g_ascii_strtod (meta[AUDIO_SIZE], NULL));
		}
		
		//hum_debug (__func__, "Converting filename to URI...\n");
		uri = g_filename_to_uri (uri, NULL, NULL);
		
		hum_app.total_song_count += 1;
		
		//hum_debug (__func__, "Inserting values for %s into the store...", uri);			
		gtk_list_store_append (hum_app.store, &iter);
		gtk_list_store_set (hum_app.store, &iter, 
			HUM_COL_URI, uri,
			HUM_COL_STATUS, "", //GTK_STOCK_MEDIA_PLAY,
			HUM_COL_TRACK_NO, track,
			HUM_COL_TITLE, title,
			HUM_COL_GENRE, genre,
			HUM_COL_ARTIST, artist,
			HUM_COL_ALBUM, album,
			HUM_COL_DURATION, duration, 
			-1);
			
		//hum_debug (__func__, "Done!\n");
		
		g_free (uri);
		g_free (track);
		g_free (title);
		g_free (genre);
		g_free (artist);
		g_free (album);
		g_free (duration);
	}
	else
	{
		hum_debug (__func__, "Error! %s\n", error->message);
	}
	
	g_clear_error (&error);
	g_strfreev (meta);
}

void hum_update_stats ()
{
	gchar *stats, *time_str, *size_str;
	
	time_str = hum_str_from_time (hum_app.total_duration);
	size_str = hum_str_from_size (hum_app.total_song_size);
	
	stats = g_strdup_printf ("%u tracks, %s, %s", hum_app.total_song_count, time_str, size_str);
	
	guint context = gtk_statusbar_get_context_id (hum_app.statusbar, "stats");
	gtk_statusbar_push (hum_app.statusbar, context, stats);
	
	g_free (time_str);
	g_free (size_str);
	g_free (stats);
	
	//hum_debug (__func__, "Done!\n");
}

void
hum_reset_ui ()
{
	if (gtk_toggle_tool_button_get_active (hum_app.play_button)) {
		/* Toggle the play button to its natural (i.e. off) state. */
		gtk_toggle_tool_button_set_active (hum_app.play_button, FALSE);
	}
	
	gtk_label_set_markup (hum_app.track_label, "<b><big>Not playing</big></b>");
	gtk_label_set_markup (hum_app.duration_label, "");
	gtk_window_set_title (hum_app.window, "Music Player");
	gtk_range_set_value (GTK_RANGE (hum_app.slider), 0.0);
}
	
void
hum_play_button_toggled (GtkWidget *b, gpointer data)
{
	if (gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (b))) 
	{
		GtkTreeIter iter;
		gchar *uri, *title, *artist, *album;
		
		gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON (b), GTK_STOCK_MEDIA_PAUSE);
		hum_debug (__func__, "Play button activated.\n");
		
		if (gtk_tree_selection_get_selected (hum_app.browse_select, NULL, &iter))
		{
			gchar *window_label, *track_label;
			
			gtk_tree_model_get (GTK_TREE_MODEL (hum_app.store), &iter, HUM_COL_URI, &uri, HUM_COL_TITLE, &title, HUM_COL_ARTIST, &artist, HUM_COL_ALBUM, &album, -1);
			
			/* Set the window title to "Artist - Track Title". */
			window_label = g_strdup_printf ("%s - %s", artist, title);
			gtk_window_set_title (hum_app.window, window_label);
			
			/* Set the track label to "Title by Artist from Album". */
			track_label = g_strdup_printf ("<big><b>%s</b></big> by <i>%s</i> from <i>%s</i>", 
				g_markup_escape_text (title, strlen (title)), 
				g_markup_escape_text (artist, strlen (artist)),
				g_markup_escape_text (album, strlen (album)));
			gtk_label_set_markup (hum_app.track_label, track_label);
			
			g_free (window_label);
			g_free (track_label);
		
			if (hum_player.playing)
			{
				hum_resume_playback ();
			}
			else
			{
				hum_start_playback (uri);
			}
		}
		else
		{
			hum_reset_ui ();
			hum_stop_playback ();
		}
		
		g_free (uri);
		g_free (title);
		g_free (artist);
		g_free (album);
	} 
	else 
	{
		gtk_tool_button_set_stock_id (GTK_TOOL_BUTTON(b), GTK_STOCK_MEDIA_PLAY);
		hum_debug (__func__, "Pause button activated.\n");
	
		hum_pause_playback ();
		
		/* Append the string "(Paused)" to the window title. */
		gtk_window_set_title (hum_app.window, g_strjoin (" ", gtk_window_get_title (hum_app.window), "(Paused)", NULL));
	}
}

void
hum_stop_button_clicked (GtkWidget *b, gpointer data)
{
	hum_debug (__func__, "Triggered.\n");
	
	hum_reset_ui ();
	hum_stop_playback ();
}

void
hum_next_button_clicked (GtkWidget *b, gpointer data)
{
	hum_debug (__func__, "Triggered.\n");
	
	GtkTreePath *path = NULL;
	GtkTreeIter iter;
	
	hum_reset_ui ();
	hum_stop_playback ();
	
	/* Find the next song in the list. If we're at the end, begin again. If no song is highlighted, stop. */
	if (gtk_tree_selection_get_selected (hum_app.browse_select, NULL, &iter))
	{
		path = gtk_tree_model_get_path (GTK_TREE_MODEL (hum_app.store), &iter);
		
		gtk_tree_path_next (path);
		
		if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (hum_app.store), &iter, path))
		{
			gtk_tree_model_get_iter_first (GTK_TREE_MODEL (hum_app.store), &iter);
			path = gtk_tree_model_get_path (GTK_TREE_MODEL (hum_app.store), &iter);
		}
		
		/* Activate the next song in the list and activate the play button. */
		gtk_tree_selection_select_path (hum_app.browse_select, path);
		gtk_tree_view_row_activated (hum_app.track_list, path, gtk_tree_view_get_column (hum_app.track_list, HUM_COL_TITLE));
	}
	
	gtk_tree_path_free (path);
}

/* 
   FIXME: This is a line-for-line duplication of the above function. To be DRY
          and future-proof, this should be split out into a hum_skip_to_path or
          something similar. 
*/
void
hum_prev_button_clicked (GtkWidget *b, gpointer data)
{
	hum_debug (__func__, "Triggered.\n");
	
	GtkTreePath *path = NULL;
	GtkTreeIter iter;
	
	hum_reset_ui ();
	hum_stop_playback ();
	
	/* Find the previous song in the list. If we're at the beginning, begin again from the end. */
	// FIXME: this doesn't make sense...
	if (gtk_tree_selection_get_selected (hum_app.browse_select, NULL, &iter))
	{
		path = gtk_tree_model_get_path (GTK_TREE_MODEL (hum_app.store), &iter);
		
		gtk_tree_path_prev (path);
		
		if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (hum_app.store), &iter, path))
		{
			gtk_tree_model_get_iter_first (GTK_TREE_MODEL (hum_app.store), &iter);
			path = gtk_tree_model_get_path (GTK_TREE_MODEL (hum_app.store), &iter);
		}
	}
	
	/* Activate the previous song in the list and activate the play button. */
	gtk_tree_selection_select_path (hum_app.browse_select, path);
	gtk_tree_view_row_activated (hum_app.track_list, path, gtk_tree_view_get_column (hum_app.track_list, HUM_COL_URI));
	
	gtk_tree_path_free (path);
}

void
hum_song_selected (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data)
{
	hum_debug (__func__, "Path is %s\n", gtk_tree_path_to_string (path));
	
	hum_stop_playback ();
	hum_reset_ui ();
	
	gtk_toggle_tool_button_set_active (hum_app.play_button, TRUE);
}

gboolean
hum_slider_moved (GtkRange *range, GtkScrollType scroll, gdouble value, gpointer data)
{
	hum_seek_playback (value / 1000000.0);
	
	return TRUE;
}
